package services;

import javax.jws.WebService;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.jboss.ws.annotation.EndpointConfig;

import data.Db;

import edu.ipfw.fitness.EquipmentCategoryType;
import edu.ipfw.fitness.EquipmentIdListType;
import edu.ipfw.fitness.EquipmentType;
import edu.ipfw.fitness.EquipmentUsageListType;
import edu.ipfw.services.equipment.EquipmentNotFoundFault;
import edu.ipfw.services.equipment.EquipmentService;
import edu.ipfw.services.equipment.EquipmentNotFound;

import java.math.BigDecimal;
import java.util.GregorianCalendar;
import java.util.Hashtable;

@WebService(serviceName = "Equipment",endpointInterface = "edu.ipfw.services.equipment.EquipmentService",targetNamespace = "http://ipfw.edu/services/equipment")
@EndpointConfig(configName="Standard WSSecurity Endpoint")
public class EquipmentServiceImpl implements EquipmentService {

	// should really place into db....
	private Hashtable<String, EquipmentType> equipmentStore = new Hashtable<String, EquipmentType>();

	// Create new database object and open the connection
	Db db = new Db();

	// Creates an Equipment in persistent storage with the given data. Assigns
	// all
	// numeric fields to 0. Sets lastMaintenanceDate to current system date.
	// Creates
	// empty usageHistory. Returns true if Equipment created/stored
	// successfully;
	// false otherwise.
	
	// Retrieves Equipment with given id from persistent storage.
	// Generates EquipmentNotFound fault if Equipment does not exist.
	public EquipmentType getEquipment(String id) throws EquipmentNotFoundFault {

		EquipmentType equipment = null;
		try {
			equipment = db.getEquipment(id);
		} catch (DatatypeConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (equipment.getId() != null) {
			return equipment;
		} else {
			throwEquipmentNotFoundException();

			return null;
		}

	}

	/*
	 * 
	 * Retrieves all occurrences of Equipment of given category, excluding
	 * usageHistory, from persistent storage. If category is not present,
	 * retrieves all occurrences of Equipment.
	 */
	public EquipmentIdListType getEquipmentList(EquipmentCategoryType arg0) {

		return db.getEquipmentList(arg0);

	}

	/*
	 * Returns usage list of Equipment Ids for Equipment due for maintenance.An
	 * Equipment is due for maintenance if either three months have passedsince
	 * lastMaintenanceDate or currentMileage is greater than or equal to 1000.
	 */
	public EquipmentIdListType getMaintenanceDue() {

		return db.getMaintenanceDue();
	}

	public EquipmentUsageListType getUsage(String arg0)
			throws EquipmentNotFoundFault {

		return db.getUsage(arg0);

	}

	public EquipmentUsageListType getUsageForDataRange(
			XMLGregorianCalendar arg0, XMLGregorianCalendar arg1, String arg2)
			throws EquipmentNotFoundFault {

		return db.getUsageForDateRange(arg0, arg1, arg2);

	}


	private void throwEquipmentNotFoundException()
			throws EquipmentNotFoundFault {
		EquipmentNotFound error = new EquipmentNotFound();
		error.setEquipmentNotFound("This piece of Equipment was not found.");
		throw new EquipmentNotFoundFault("EquipmentNotFound", error);
	}
	

	// Create new database object and open the connection


	// Creates an Equipment in persistent storage with the given data. Assigns
	// all
	// numeric fields to 0. Sets lastMaintenanceDate to current system date.
	// Creates
	// empty usageHistory. Returns true if Equipment created/stored
	// successfully;
	// false otherwise.
	public boolean add(String id, EquipmentCategoryType category,
			String description) {
		boolean result = false;
		try {

			// Using Database
			result = db.addEquipment(id, description, category.value(),
					getCurrentDateTime());

			/*
			 * Original
			 * 
			 * EquipmentType newEquipment = new EquipmentType();
			 * 
			 * // Assign values that were passed in // Set id to the id
			 * parameter that was passed in newEquipment.setId(id); // Set
			 * category to the category parameter that was passed in
			 * newEquipment.setCategory(category); // Set description to the
			 * description parameter that was passed in
			 * newEquipment.setDescription(description);
			 * 
			 * // Set numerics to 0 // Set Initial Total Mileage to 0 BigDecimal
			 * initialTotalMileage = new BigDecimal("0");
			 * newEquipment.setTotalMileage(initialTotalMileage);
			 * 
			 * // Set Total Time to 0
			 * newEquipment.setTotalTime(DatatypeFactory.newInstance
			 * ().newDuration(0));
			 * 
			 * // Set Initial Current Mileage to 0 BigDecimal
			 * initialCurrentMileage = new BigDecimal("0");
			 * newEquipment.setCurrentMileage(initialCurrentMileage);
			 * 
			 * // Set Current Time to 0
			 * newEquipment.setCurrentTime(DatatypeFactory
			 * .newInstance().newDuration(0));
			 * 
			 * // Set Last Maintenance Date to current system date
			 * newEquipment.setLastMaintenanceDate(getCurrentDateTime());
			 * 
			 * // Create empty Usage History newEquipment.setUsageHistory(new
			 * EquipmentUsageListType());
			 * 
			 * equipmentStore.put(id, newEquipment);
			 */
		} catch (Exception ex) {
			ex.printStackTrace();
			return result;
		}

		return result;
	}

	

	// Updates Equipment in persistent storage with given id. Sets
	// lastMaintenanceDate
	// to current system date. Sets currentMileage and currentTime to 0. Returns
	// true
	// if Equipment updated successfully; false otherwise. Generates
	// EquipmentNotFound
	// fault if Equipment does not exist.
	public boolean maintain(String id) throws EquipmentNotFoundFault {

		boolean result = false;

		try {
			result = db.maintain(id, getCurrentDateTime());
		} catch (DatatypeConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return result;

		/*
		 * if (equipmentStore.containsKey(id)) { try { // Set Last Maintenance
		 * Date to the current system date/time
		 * equipmentStore.get(id).setLastMaintenanceDate(getCurrentDateTime());
		 * 
		 * // Set Current Mileage to 0 BigDecimal initialCurrentMileage = new
		 * BigDecimal("0");
		 * equipmentStore.get(id).setCurrentMileage(initialCurrentMileage);
		 * 
		 * // Set the Current Time to 0
		 * equipmentStore.get(id).setCurrentTime(DatatypeFactory
		 * .newInstance().newDuration(0)); } catch(Exception ex) {
		 * throwEquipmentNotFoundException(); } } else {
		 * throwEquipmentNotFoundException(); }
		 * 
		 * return true;
		 */
	}

	/*
	 * Adds entry to usageHistory. Updates currentMileage, totalMileage,
	 * currentTime, and totalTime.
	 */
	public boolean recordUsage(String arg0, XMLGregorianCalendar arg1,
			XMLGregorianCalendar arg2, float arg3)
			throws EquipmentNotFoundFault {
		
		boolean result = false;
		
		try{
			result = db.recordUsage(arg0,arg1,arg2,arg3);
		}
		catch(Exception e)
		{
			throwEquipmentNotFoundException();
		}
	 

		return result;
	}

	// Removes Equipment with given id from persistent storage. Returns true if
	// Equipment
	// removed successfully; false otherwise. Generates EquipmentNotFound fault
	// if Equipment
	// does not exist.
	public boolean remove(String id) throws EquipmentNotFoundFault {
		
		
		if (db.removeEquipment(id)) {

			return true;
		} else {
			throwEquipmentNotFoundException();
		}
		return false;
	}

	private XMLGregorianCalendar getCurrentDateTime()
			throws DatatypeConfigurationException {
		GregorianCalendar gc = new GregorianCalendar();
		XMLGregorianCalendar dtf = null;
		dtf = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);

		return dtf;
	}





}
